package com.starsoft.verifycode.feature;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class SimpleFeature {

	public String get(BufferedImage image) {
		int iw = image.getWidth();
		int ih = image.getHeight();
		StringBuilder result = new StringBuilder();
		for (int i = 0; i < ih; i++) {
			for (int j = 0; j < iw; j++) {
				result.append(notBlank(image.getRGB(j, i)));
			}
		}
		return result.toString();
	}

	public String match(String source, List<FeatureLib> libs) {
		int minDistance = source.length();
		FeatureLib target = null;
		for (FeatureLib lib : libs) {
			int distance = getDistance(source, lib.getValue());
			if (distance < minDistance) {
				target = lib;
				minDistance = distance;
			}
		}
		return target.getName();
	}

	public int getDistance(String source, String target) {
		if (source.length() != target.length()) {
			throw new RuntimeException("Length not same");
		}
		int count = 0;
		for (int i = 0; i < source.length(); i++) {
			if (source.charAt(i) != target.charAt(i)) {
				count++;
			}
		}
		return count;
	}

	private int notBlank(int colorInt) {
		final Color color = new Color(colorInt);
		if (color.getRed() + color.getGreen() + color.getBlue() > 400) {
			return 0;
		}
		return 1;
	}

	public List<FeatureLib> compressLib(List<FeatureLib> libs) {
		Map<String, List<FeatureLib>> newMap = new HashMap<String, List<FeatureLib>>();
		for (FeatureLib lib : libs) {
			String name = lib.getName();
			if (!newMap.containsKey(name)) {
				List<FeatureLib> libList = Arrays.asList(lib);
				newMap.put(name, libList);
			} else {
				List<FeatureLib> libList = newMap.get(name);
				boolean hasSame = false;
				for (FeatureLib cmplib : libList) {
					double distance = getDistance(cmplib.getValue(), lib.getValue());
					distance = distance / cmplib.getValue().length();
					if (distance < 0.02) {
						hasSame = true;
						break;
					}
				}
				if (!hasSame) {
					libList.add(lib);
				}
			}
		}
		List<FeatureLib> newLibs = new ArrayList<FeatureLib>();
		for (List<FeatureLib> libList : newMap.values()) {
			newLibs.addAll(libList);
		}
		return newLibs;
	}

	public List<FeatureLib> loadLibs(String libStr) {
		String[] libStrSplit = libStr.trim().split(",");
		List<FeatureLib> libs = new ArrayList<FeatureLib>();
		for (String str : libStrSplit) {
			String[] strSplit = str.split("=");
			libs.add(new FeatureLib(strSplit[0].trim(), strSplit[1].trim()));
		}
		return libs;
	}

	public String getLibStr(List<FeatureLib> libs) {
		return libs.toString();
	}

	public List<FeatureLib> loadLibs(File libFile) {
		InputStream is;
		try {
			is = new FileInputStream(libFile);
			return loadLibs(is);
		} catch (FileNotFoundException e) {
			throw new RuntimeException(e);
		}
	}
	
	public List<FeatureLib> loadLibs(InputStream is) {
		BufferedReader reader = null;
		try {
			StringBuilder libStr = new StringBuilder();
			reader = new BufferedReader(new InputStreamReader(is));
			String line = null;
			while ((line = reader.readLine()) != null) {
				libStr.append(line);
			}
			return loadLibs(libStr.toString());
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally{
			try {
				reader.close();
				is.close();
			} catch (IOException e) {
			}
		}
	}
}
